﻿using DotNetCore.CAP;
using Microsoft.Extensions.Logging;
using SHKF.B2C.BaseHosted;
using SkyApm;
using SkyApm.Tracing;
using SkyApm.Tracing.Segments;
using System;
using System.Collections.Generic;

namespace SHKF.B2C.Hosted
{
    /// <summary>
    /// skywalking, cap
    /// </summary>
    public class HostedController : BaseController
    {
        private readonly ITracingContext _tracingContext;
        protected readonly IEntrySegmentContextAccessor segContext;  //skywalking
        protected readonly ICapPublisher capPublisher;              //cap
        private readonly IBase64Formatter base64Formatter;

        public HostedController(IServiceProvider serviceProvider,
            ILogger<BaseController> logger):base(logger)
        {
            this.segContext = (IEntrySegmentContextAccessor)serviceProvider.GetService(typeof(IEntrySegmentContextAccessor));
            this.capPublisher = (ICapPublisher)serviceProvider.GetService(typeof(ICapPublisher));  

            this.base64Formatter = (IBase64Formatter)serviceProvider.GetService(typeof(IBase64Formatter));
            this._tracingContext = (ITracingContext)serviceProvider.GetService(typeof(ITracingContext));
        }


        protected string CreateTraceId()
        {
            string TraceId = segContext.Context.TraceId;
            return TraceId;
        }

        protected void Publish<T>(string name, T contentObj, string strTraceId)
        {
            //Dictionary<string, string> headers = new Dictionary<string, string>();
            //headers.Add(TraceId, strTraceId);
            //headers.Add("segmentId", this.segContext.Context.SegmentId);
            //headers.Add("parentSpanId", this.segContext.Context.Span.SpanId.ToString());
            //headers.Add("parentService", this.segContext.Context.ServiceId);
            //headers.Add("parentServiceInstance", this.segContext.Context.ServiceInstanceId);
            //headers.Add("parentEndpoint", this.segContext.Context.Span.OperationName.ToString());
            //headers.Add("networkAddress", this.segContext.Context.Span.Peer.ToString());

            List<string> sw8 = new List<string>();

        
            sw8.Add("1");                                   //0. 
            sw8.Add(base64Formatter.Encode(strTraceId));    //1.TraceId 
            sw8.Add(base64Formatter.Encode(this.segContext.Context.SegmentId));     //2.segmentId
            sw8.Add(this.segContext.Context.Span.SpanId.ToString());                //3.parentSpanId
            sw8.Add(base64Formatter.Encode(this.segContext.Context.ServiceId));                         //4.parentService
            sw8.Add(base64Formatter.Encode(this.segContext.Context.ServiceInstanceId));                 //5.parentServiceInstance
            sw8.Add(base64Formatter.Encode(this.segContext.Context.Span.OperationName.ToString()));     //6.parentEndpoint
            sw8.Add(base64Formatter.Encode(this.segContext.Context.Span.Peer.ToString()));              //7.networkAddress

            string strSw8 = string.Join("-", sw8); 
            Dictionary<string, string> headers = new Dictionary<string, string>();
            headers.Add("sw8", strSw8);
            this.capPublisher.Publish(name, contentObj, headers);

        }

        protected void AddLog(string log)
        {
            LogEvent custom = new LogEvent("custom", log);
            this.segContext.Context.Span.AddLog(custom);

        }
        
        protected void Release()
        { 
            _tracingContext.Release(this.segContext.Context);
        }

    }
}
